using System;
using System.Runtime.CompilerServices;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting;

namespace Mono4Delphi
{
	
	
	public class TProxyAnyIntf : RealProxy
	{
	  IntPtr FhInstance = IntPtr.Zero;	
		
		//System.Collections.Generic.List`1[System.Int32]
		public static object CreateGenericType(string aTypeName)
		{
			Type lType = Type.GetType(aTypeName);						
			object lInstance = Activator.CreateInstance(lType);
			return lInstance;
		}

	  public IntPtr GetHInstance()
		{
			return FhInstance;
		}
		
	  public static object CreateAsType(string aTypeName, IntPtr aHInstance)
		{

			TProxyAnyIntf p = new TProxyAnyIntf(Type.GetType(aTypeName), aHInstance);
			return p.GetTransparentProxy();
		}
		
	  public static object CreateAsType(Type aType, IntPtr aHInstance)
		{
			TProxyAnyIntf p = new TProxyAnyIntf(aType, aHInstance);
			return p.GetTransparentProxy();
		}
		
	  public TProxyAnyIntf(Type type, IntPtr hInstance)
					 : base(type)
	  {
			FhInstance = hInstance;
	  } // ctor

	  [MethodImplAttribute(MethodImplOptions.InternalCall)]
	  extern static object DelphiInvoke(object aProxy, IntPtr hIntance, string TypeName, string MethodName, object[] Args);

	  //[MethodImplAttribute(MethodImplOptions.InternalCall)]
	  //extern static object DelphiInvokeExt(string TypeName, string MethodName, object[] Args);

	  public override IMessage Invoke(IMessage msg)
	  {
		 IMethodCallMessage m = (IMethodCallMessage)msg;

	 	 object returnValue;	
		 if (m.MethodName == "GetHInstance")
			returnValue = GetHInstance();
		else
		    returnValue = DelphiInvoke(this, FhInstance, m.MethodBase.ReflectedType.ToString(), m.MethodName, m.Args);

		 return new ReturnMessage(returnValue, m.Args, m.ArgCount, m.LogicalCallContext, m);
	  }
	}
}
